package com.cy.jt.security.config;

import com.cy.jt.security.config.handler.DefaultAccessDeniedExceptionHandler;
import com.cy.jt.security.config.handler.DefaultAuthenticationEntryPoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * 由@Configuration注解描述的类spring中的配置类,配置类会在
 * spring工程启动时优先加载,在配置类中通常会对第三方资源进行初始配置
 * @EnableGlobalMethodSecurity 注解由SpringSecurity提供,用于描述权限配置类,
 * 告诉系统底层在启动时,进行访问权限的初始化
 */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //对http请求的安全控制进行配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //1.关闭跨域攻击
        http.csrf().disable();
        //2.配置登录url(登录表单使用哪个页面)
        http.formLogin()
                .loginPage("/login.html")//登录页面
                .loginProcessingUrl("/login")//与form表单中的action值相对应
                .defaultSuccessUrl("/index.html");//内部做了重定向的操作.https的网址才会跳转
//                .successHandler(new RedirectAuthenticationSuccesHandler("http://www.tedu.cn"));
//                .successForwardUrl("/index");//请求转发(controller中的一个方法)
//                .failureUrl("/login.html?error");//登录失败(默认)
//                .successHandler(new DefaultAuthenticationSuccessHandler())
//                .failureHandler(new DefaultAuthenticationFailureHandler());
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login.html");

        //设置需要认证与拒绝访问的异常处理器
        http.exceptionHandling()
                .authenticationEntryPoint(new DefaultAuthenticationEntryPoint())//没有授权
                .accessDeniedHandler(new DefaultAccessDeniedExceptionHandler());

        //3.放行登录url(不需要认证就可以访问)
        http.authorizeRequests().antMatchers("/login.html")
                .permitAll()//允许直接访问
                .anyRequest().authenticated();//除了以上资源必须认证才可以访问
    }
    /**
     * @Bean 注解通常在@Configuration注解描述的类中描述方法,
     * 用于告诉spring框架这个方法的返回值会交给spring管理
     * 并给spring管理的对象起个默认的名字,这个名字与方法名相同,
     * 当然也可以通过@Bean注解起名字
     */
    @Bean("bcryptPasswordEncoder")
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}
